package br.com.assinchronus.negocio;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;

import br.com.assinchronus.componentes.Casa;
import br.com.assinchronus.componentes.Dama;
import br.com.assinchronus.componentes.Pecas;
import br.com.assinchronus.util.RegraUtil;

public class RegraPeao {

	private final Logger log = Logger.getLogger(this.getClass().getName());

	public JogadasEnum verificaJogada(Casa casaAtual, Casa casaFinal, Casa[] tabuleiro, boolean sequencia) {
		int posicaoAtual = casaAtual.getPosicao();
		int posicaoFinal = 0;

		if (casaFinal != null && casaFinal.getPeca() == null) {
			posicaoFinal = casaFinal.getPosicao();
		} else {
			return JogadasEnum.INVALIDA;
		}

		Pecas peca = casaAtual.getPeca();

		if (!sequencia) {
			if (peca.getCor() == Pecas.BRANCA) {
				if ((posicaoAtual - posicaoFinal == -5) || (posicaoAtual - posicaoFinal == -4)) {
					return JogadasEnum.MOVER_BRANCA;
				} else if ((posicaoAtual - posicaoFinal == -10) || (posicaoAtual - posicaoFinal == -8)) {
					return verificaJogadaComer(tabuleiro, posicaoAtual, casaFinal, casaAtual.getPeca().getCor());
				}
			} else if (peca.getCor() == Pecas.PRETA) {
				if ((posicaoAtual - posicaoFinal == 4) || (posicaoAtual - posicaoFinal == 5)) {
					return JogadasEnum.MOVER_PRETA;
				} else if ((posicaoAtual - posicaoFinal == 10) || (posicaoAtual - posicaoFinal == 8)) {
					return verificaJogadaComer(tabuleiro, posicaoAtual, casaFinal, casaAtual.getPeca().getCor());
				}
			}
		} else {
			if (peca.getCor() == Pecas.BRANCA) {
				if ((posicaoAtual - posicaoFinal == -5) || (posicaoAtual - posicaoFinal == -4)) {
					return verificaJogadaComer(tabuleiro, posicaoAtual, casaFinal, casaAtual.getPeca().getCor());
				} else if ((posicaoAtual - posicaoFinal == -10) || (posicaoAtual - posicaoFinal == -8)) {
					return verificaJogadaComer(tabuleiro, posicaoAtual, casaFinal, casaAtual.getPeca().getCor());
				} else if ((posicaoAtual - posicaoFinal == 4) || (posicaoAtual - posicaoFinal == 5)) {
					return verificaJogadaComer(tabuleiro, posicaoAtual, casaFinal, casaAtual.getPeca().getCor());
				} else if ((posicaoAtual - posicaoFinal == 10) || (posicaoAtual - posicaoFinal == 8)) {
					return verificaJogadaComer(tabuleiro, posicaoAtual, casaFinal, casaAtual.getPeca().getCor());
				}
			} else if (peca.getCor() == Pecas.PRETA) {
				if ((posicaoAtual - posicaoFinal == 4) || (posicaoAtual - posicaoFinal == 5)) {
					return verificaJogadaComer(tabuleiro, posicaoAtual, casaFinal, casaAtual.getPeca().getCor());
				} else if ((posicaoAtual - posicaoFinal == 10) || (posicaoAtual - posicaoFinal == 8)) {
					return verificaJogadaComer(tabuleiro, posicaoAtual, casaFinal, casaAtual.getPeca().getCor());
				} else if ((posicaoAtual - posicaoFinal == -5) || (posicaoAtual - posicaoFinal == -4)) {
					return verificaJogadaComer(tabuleiro, posicaoAtual, casaFinal, casaAtual.getPeca().getCor());
				} else if ((posicaoAtual - posicaoFinal == -10) || (posicaoAtual - posicaoFinal == -8)) {
					return verificaJogadaComer(tabuleiro, posicaoAtual, casaFinal, casaAtual.getPeca().getCor());
				}
			}
		}

		return JogadasEnum.INVALIDA;
	}

	// TODO: Refatorar esse metodo para que receba uma casa no lugar de
	// posicaoAtual, assim não vai mais precisa da cor.
	private JogadasEnum verificaJogadaComer(Casa[] tabuleiro, int posicaoAtual, Casa casaFinal, int cor) {
		if (casaFinal.getPeca() != null) {
			return JogadasEnum.INVALIDA;
		}

		int posicaoIntermediaria = (posicaoAtual + casaFinal.getPosicao()) / 2;
		Pecas peca = tabuleiro[posicaoIntermediaria].getPeca();
		if (peca != null && peca.getCor() != cor) {
			return JogadasEnum.COMER;
		}

		return JogadasEnum.INVALIDA;
	}

	public Map<Casa, List<Casa>> verificaObrigatoria(Casa[] tab, int cor) {
		Map<Casa, List<Casa>> obrigatorias = new HashMap<Casa, List<Casa>>();

		for (int i = 1; i < tab.length; i++) {
			if (i % 9 == 0 || (tab[i].getPeca() == null || tab[i].getPeca() instanceof Dama || tab[i].getPeca().getCor() != cor)) {
				continue;
			}

			if (tab[i].getPeca().getCor() == Pecas.BRANCA) {
				if (i + 5 < 36) {
					Casa casa = tab[i + 5];
					if (casa != null && casa.getPeca() != null && casa.getPeca().getCor() == Pecas.PRETA && i + 10 < 36) {
						if (verificaJogada(tab[i], tab[i + 10], tab, false) == JogadasEnum.COMER) {
							RegraUtil.inserirNoMap(tab[i], tab[i + 10], obrigatorias);
						}
					}
				}
				if (i + 4 < 36) {
					Casa casa = tab[i + 4];
					if (casa != null && casa.getPeca() != null && casa.getPeca().getCor() == Pecas.PRETA && i + 8 < 36) {
						if (verificaJogada(tab[i], tab[i + 8], tab, false) == JogadasEnum.COMER) {
							RegraUtil.inserirNoMap(tab[i], tab[i + 8], obrigatorias);
						}
					}
				}
			} else {
				if (i - 5 > 0) {
					Casa casa = tab[i - 5];
					if (casa != null && casa.getPeca() != null && casa.getPeca().getCor() == Pecas.BRANCA && i - 10 > 0) {
						if (verificaJogada(tab[i], tab[i - 10], tab, false) == JogadasEnum.COMER) {
							RegraUtil.inserirNoMap(tab[i], tab[i - 10], obrigatorias);
						}
					}
				}
				if (i - 4 > 0) {
					Casa casa = tab[i - 4];
					if (casa != null && casa.getPeca() != null && casa.getPeca().getCor() == Pecas.BRANCA && i - 8 > 0) {
						if (verificaJogada(tab[i], tab[i - 8], tab, false) == JogadasEnum.COMER) {
							RegraUtil.inserirNoMap(tab[i], tab[i - 8], obrigatorias);
						}
					}
				}
			}

		}

		return obrigatorias;
	}

	/**
	 * 
	 * @param casaAtual
	 *            Casa que será analisada
	 * @param tab
	 *            Tabuleiro atual do jogo
	 * @param cor
	 *            Cor adversaria
	 * @return
	 */
	public List<Casa> verificaSequencia(Casa casaAtual, Casa[] tab) {
		List<Casa> listCasas = new ArrayList<Casa>();
		int cor = casaAtual.getPeca().getCor();

		int posicao = casaAtual.getPosicao();

		int adv = posicao - 5;
		if (adv - 5  > 0 && adv % 9 != 0 && tab[adv].getPeca() != null && tab[adv].getPeca().getCor() != cor && !tab[adv].getPeca().isCapturada()) {
			int casaFinal = posicao - 10;
			if ( posicao -10 > 0 && verificaJogada( casaAtual, tab[casaFinal], tab, true) == JogadasEnum.COMER && casaAtual.getPeca().getCor() != tab[adv].getPeca().getCor()) {
				listCasas.add(tab[casaFinal]);
				log.debug("Sequencia ".concat(tab[casaFinal].toString()));
			}
		}

		adv = posicao - 4;
		if (adv - 4 > 0 && adv % 9 != 0 && tab[adv].getPeca() != null && tab[adv].getPeca().getCor() != cor && !tab[adv].getPeca().isCapturada()) {
			if (posicao -8 >0 && verificaJogada(casaAtual, tab[posicao - 8], tab, true) == JogadasEnum.COMER && casaAtual.getPeca().getCor() != tab[adv].getPeca().getCor()) {
				listCasas.add(tab[posicao - 8]);
				log.debug("Sequencia ".concat(tab[posicao - 8].toString()));
			}
		}

		adv = posicao + 5;
		if (adv + 5 < 36 && adv % 9 != 0 && tab[adv].getPeca() != null && tab[adv].getPeca().getCor() != cor && !tab[adv].getPeca().isCapturada()) {
			if (posicao +10 <36 && verificaJogada(casaAtual, tab[posicao + 10], tab, true) == JogadasEnum.COMER && casaAtual.getPeca().getCor() != tab[adv].getPeca().getCor()) { 
				listCasas.add(tab[posicao + 10]);
			}
		}

		adv = posicao + 4;
		if (adv + 4 < 36 && adv % 9 != 0 && tab[adv].getPeca() != null && tab[adv].getPeca().getCor() != cor && !tab[adv].getPeca().isCapturada()) {
			if (posicao + 8 < 36 && verificaJogada(casaAtual, tab[posicao + 8], tab, true) == JogadasEnum.COMER && casaAtual.getPeca().getCor() != tab[adv].getPeca().getCor()) {
				listCasas.add(tab[posicao + 8]);
				log.debug("Sequencia ".concat(tab[posicao + 8].toString()));
			}
		}

		return listCasas;
	}
}